package com.letoken.platform.app.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.letoken.platform.app.consumer.FundConsumer;
import com.letoken.platform.app.consumer.FundReleaseConsumer;
import com.letoken.platform.app.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.letoken.platform.pub.constant.RedisKeyConstant;
import com.letoken.platform.pub.enums.*;
import com.letoken.platform.pub.exception.ApiServiceException;
import com.letoken.platform.repo.admin.dao.AdminCommunityConfigMapper;
import com.letoken.platform.repo.admin.dao.AdminFundConfigMapper;
import com.letoken.platform.repo.admin.po.AdminFundConfig;
import com.letoken.platform.repo.app.dao.*;
import com.letoken.platform.repo.app.manager.AppUserManager;
import com.letoken.platform.repo.app.po.*;
import com.letoken.platform.repo.app.redis.RedisConfig;
import com.letoken.platform.repo.app.req.user.FundTransferReq;
import com.letoken.platform.repo.app.req.user.UserLevelReq;
import com.letoken.platform.repo.helper.CalculateConsumerValue;
import com.letoken.platform.repo.utlis.UniqueIDUtils;
import com.letoken.platform.repo.performance.TeamPerformanceService;
import com.letoken.platform.repo.utlis.UniqueIDUtils;
import com.letoken.platform.repo.utlis.lock.Lock;
import com.letoken.platform.repo.utlis.lock.LockCategoryEnum;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 作者
 * @since 2023-08-04
 */
@Service
@Slf4j
public class AppFundInfoServiceImpl extends ServiceImpl<AppFundInfoMapper, AppFundInfo> implements AppFundInfoService {

    @Autowired
    AppUserWalletService appUserWalletService;

    @Resource
    AppUserWalletMapper appUserWalletMapper;

    @Resource
    AppUserAssetsHistoryMapper appUserAssetsHistoryMapper;

    @Autowired
    private AppFundInfoService appFundInfoService;

    @Autowired
    private AppUserManager appUserManager;

    @Resource
    private AppUserTeamPathMapper appUserTeamPathMapper;

    @Resource
    private AppUserTeamMapper appUserTeamMapper;

    @Autowired
    private AppUserTeamService appUserTeamService;

    @Resource
    private AdminFundConfigMapper adminFundConfigMapper;

    @Resource
    private AppFundLevelInfoMapper appFundLevelInfoMapper;

    @Resource
    private AdminFundLevelConfigMapper adminFundLevelConfigMapper;

    @Autowired
    private AppFundRankInfoMapper appFundRankInfoMapper;

    @Autowired
    private AppFundRankingMapper appFundRankingMapper;

    @Autowired
    private AdminFundDistributeConfigMapper adminFundDistributeConfigMapper;

    @Autowired
    private AppFundInfoMapper appFundInfoMapper;

    @Autowired
    CalculateConsumerValue calculateConsumerValue;

    @Autowired
    AppUserLampService appUserLampService;

    @Resource
    AppFundV2InfoMapper appFundV2InfoMapper;

    @Resource
    AdminCommunityConfigMapper adminCommunityConfigMapper;

    @Resource
    private RedisConfig redisConfig;

    @Resource
    private TeamPerformanceService teamPerformanceService;

    private static final BigDecimal menkang = new BigDecimal("1000");

    private static final BigDecimal giveRate = new BigDecimal(0.1);


    @Override
    @Transactional
    public void transferIn(FundTransferReq req) {
        AppUserWallet w = appUserWalletMapper.selectForUpdate(req.getWalletId());
        if (w.getAvailableBalance().compareTo(req.getAmount()) < 0) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_053);
        }

        AppUserWallet updateW = new AppUserWallet();
        updateW.setId(w.getId());
        updateW.setAvailableBalance(w.getAvailableBalance().subtract(req.getAmount()));
        appUserWalletMapper.updateById(updateW);
        BigDecimal afterAmout = BigDecimal.ZERO;

        BigDecimal afterGiveAmout = BigDecimal.ZERO;
        AppFundV2Info appFundV2Info = appFundV2InfoMapper.selectBYUserId(req.getUserId());
        if (ObjectUtils.isEmpty(appFundV2Info)) {
            appFundV2Info = new AppFundV2Info();
            if (req.getAmount().compareTo(menkang) >= 0) {
                appFundV2Info.setGive(req.getAmount().multiply(giveRate));
                afterGiveAmout = appFundV2Info.getGive();
            }


            appFundV2Info.setUserId(req.getUserId());
            appFundV2Info.setRetained(req.getAmount().multiply(new BigDecimal("2")));
            appFundV2Info.setCreateTime(LocalDateTime.now());
            appFundV2Info.setFund(req.getAmount());
            appFundV2Info.insert();

            afterAmout = appFundV2Info.getRetained();

        } else {
            appFundV2Info = appFundV2InfoMapper.selectForUpdate(req.getUserId());
            AppFundV2Info appFundV2Info1 = new AppFundV2Info();
            if (req.getAmount().compareTo(menkang) >= 0) {
                appFundV2Info1.setGive(appFundV2Info.getGive().add(req.getAmount().multiply(giveRate)));
                afterGiveAmout = appFundV2Info1.getGive();
            }

            appFundV2Info1.setRetained(appFundV2Info.getRetained().add(req.getAmount().multiply(new BigDecimal("2"))));
            appFundV2Info1.setFund(appFundV2Info.getFund().add(req.getAmount()));
            appFundV2Info1.setUpdateTime(LocalDateTime.now());
            appFundV2Info1.setUserId(appFundV2Info.getUserId());
            appFundV2InfoMapper.updateById(appFundV2Info1);
            afterAmout = appFundV2Info1.getRetained();

        }

        AppFundV2Detail appFundV2Detail = new AppFundV2Detail();
        appFundV2Detail.setAmount(req.getAmount().multiply(new BigDecimal("2")));
        appFundV2Detail.setUserId(req.getUserId());
        appFundV2Detail.setCreateTime(LocalDateTime.now());
        appFundV2Detail.setAfterAmount(afterAmout);
        appFundV2Detail.setType(1);
        appFundV2Detail.insert();

        //String seqNo = UniqueIDUtils.genSeqNo("AB");
        AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
        assetHistory.setUserId(req.getUserId());
        assetHistory.setType(TokenTransactionTypeEnum.FUND_ISSUE.getValue());
        assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
        assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
        assetHistory.setAmount(req.getAmount().negate());
        assetHistory.setSn(appFundV2Detail.getId().toString());
        assetHistory.setBalance(updateW.getAvailableBalance());
        assetHistory.setCreateTime(LocalDateTime.now());
        assetHistory.setUpdateTime(assetHistory.getCreateTime());
        appUserAssetsHistoryMapper.insert(assetHistory);

        if(req.getAmount().compareTo(menkang)>=0){
            AppFundV2Detail appFundV2Detail2 = new AppFundV2Detail();
            appFundV2Detail2.setAmount(req.getAmount().multiply(giveRate));
            appFundV2Detail2.setUserId(req.getUserId());
            appFundV2Detail2.setCreateTime(LocalDateTime.now());
            appFundV2Detail2.setAfterAmount(afterGiveAmout);
            appFundV2Detail2.setType(9);
            appFundV2Detail2.insert();
        }


        AppUser user = appUserManager.queryMe();

      /*  AdminFundDistributeConfig config =  adminFundDistributeConfigMapper.selectById(1);
        AppFundRankInfo appFundRankInfo = appFundRankInfoMapper.getRankInfoForupdate();
        appFundRankInfo.setDayAmount(config.getDayRate().multiply(req.getAmount()).add(appFundRankInfo.getDayAmount()));
        appFundRankInfo.setWeekAmout(config.getWeekRate().multiply(req.getAmount()).add(appFundRankInfo.getWeekAmout()));
        appFundRankInfo.updateById();*/


        if (!user.getInviterId().equals(0)) {
            AdminFundConfig adminFundConfig = new AdminFundConfig();
            adminFundConfig.setEcoRate(new BigDecimal("0.008"));
            req.setAdminFundConfig(adminFundConfig);
            //修改生态建设
            upgradeUPdate(user.getId(), req.getAmount(), req.getAdminFundConfig());
            //平级奖/服务奖
            peerLevelReward(user.getId(), req.getAmount());
            //修改等级
            updateLevel(user.getInviterId());

            //社区服务奖
            communityReward(user.getId(), req.getAmount());

            communityV2Reward(user.getId(), req.getAmount());

            appUserLampService.updateLamd(user.getId(),req.getAmount());

            // 增加业绩
            addTeamValue(user.getId(), req.getAmount());
            //日周排行榜
            addOrUpdateRanking(user.getInviterId(), req.getAmount());
        }
        AppUserTeam appUserTeam = appUserTeamMapper.selectById(user.getId());
        appUserTeam.setFundCchievement(appUserTeam.getFundCchievement().add(req.getAmount()));
        appUserTeam.setUpdateTime(LocalDateTime.now());
        appUserTeam.updateById();

        teamPerformanceService.add(TeamPerformanceTypeEnum.Fund, req.getUserId(), req.getAmount());
    }


    @Override
    @Lock(ce = LockCategoryEnum.ID, field = "userId", value = "FUND:TRANSFER", expire = 3l)
    public void transferInUpdate(FundTransferReq req) {
        AppUserWallet w = appUserWalletMapper.selectForUpdate(req.getWalletId());
        if (w.getAvailableBalance().compareTo(req.getAmount()) < 0) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_053);
        }
        if (req.getAmount().compareTo(req.getAdminFundConfig().getMin()) < 0) {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_053, req.getAdminFundConfig().getMin());
        }
        AppUserWallet updateW = new AppUserWallet();
        updateW.setId(w.getId());
        updateW.setAvailableBalance(w.getAvailableBalance().subtract(req.getAmount()));
        appUserWalletMapper.updateById(updateW);

        AppFundInfo appFundInfo = new AppFundInfo();
        appFundInfo.setUserId(req.getUserId());
        appFundInfo.setFundId(req.getAdminFundConfig().getId());
        appFundInfo.setRate(req.getAdminFundConfig().getRate());
        appFundInfo.setAmount(req.getAmount().multiply(req.getAdminFundConfig().getRate()));
        appFundInfo.setFund(req.getAmount());
        appFundInfo.setExpirationTime(LocalDateTime.now().plusDays(req.getAdminFundConfig().getDate()));
        appFundInfo.setCreateTime(LocalDateTime.now());
        appFundInfo.setType(1);
        appFundInfo.setState(1);
        appFundInfoService.save(appFundInfo);

        //String seqNo = UniqueIDUtils.genSeqNo("AB");
        AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
        assetHistory.setUserId(req.getUserId());
        assetHistory.setType(TokenTransactionTypeEnum.FUND_ISSUE.getValue());
        assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
        assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
        assetHistory.setAmount(req.getAmount().negate());
        assetHistory.setSn(appFundInfo.getId().toString());
        assetHistory.setBalance(updateW.getAvailableBalance());
        assetHistory.setCreateTime(LocalDateTime.now());
        assetHistory.setUpdateTime(assetHistory.getCreateTime());
        appUserAssetsHistoryMapper.insert(assetHistory);
        AppUserTeam user = appUserManager.queryLevelByUserId(req.getUserId());


        AppFundDetail appFundDetail = new AppFundDetail();
        appFundDetail.setUserId(req.getUserId());
        appFundDetail.setType(4);
        appFundDetail.setAmount(req.getAmount());
        appFundDetail.setState(req.getAdminFundConfig().getId());
        appFundDetail.setCreateTime(LocalDateTime.now());
        appFundDetail.insert();


        //变更奖金池
        if (!user.getInviterId().equals(0)) {
            if (req.getFundId() >= 3) {
                upgradeUPdate(user.getUserId(), req.getAmount(), req.getAdminFundConfig());
                peerLevelReward(user.getUserId(), req.getAmount());
            }

            addTeamValue(user.getUserId(), req.getAmount());
            updateLevel(user.getInviterId());

        }
        AppUserTeam appUserTeam = appUserTeamMapper.selectById(user.getUserId());
        appUserTeam.setFundCchievement(appUserTeam.getFundCchievement().add(req.getAmount()));
        appUserTeam.setUpdateTime(LocalDateTime.now());
        appUserTeam.updateById();

        AppUserLamp appUserLamp = appUserLampService.getById(user.getUserId());
        if (ObjectUtils.isEmpty(appUserLamp)) {
            appUserLamp = new AppUserLamp();
            appUserLamp.setUserId(user.getUserId());
            appUserLamp.setUserPerformance(req.getAmount());
            appUserLamp.insert();
        } else {
            appUserLamp.setUserPerformance(appUserLamp.getUserPerformance().add(req.getAmount()));
            appUserLamp.setUdpateTime(LocalDateTime.now());
            appUserTeam.updateById();
        }
    }

    @Override
    @Lock(ce = LockCategoryEnum.ID, field = "userId", value = "FUND:TRANSFER", expire = 3l)
    public void fundResumption(AppFundInfo appFundInfo) {
        List<AdminFundConfig> configList = adminFundConfigMapper.selectList(new QueryWrapper<>());
        AdminFundConfig adminFundConfig = configList.stream().filter(s -> s.getId().equals(appFundInfo.getFundId())).collect(Collectors.toList()).get(0);
        AppFundInfo appFundInfo1 = new AppFundInfo();
        appFundInfo1.setId(appFundInfo.getId());
        appFundInfo1.setExpirationTime(LocalDateTime.now().plusDays(adminFundConfig.getDate()));
        appFundInfo1.updateById();
        AppUserTeam user = appUserManager.queryLevelByUserId(appFundInfo.getUserId());

        AppFundDetail appFundDetail2 = new AppFundDetail();
        appFundDetail2.setUserId(appFundInfo.getUserId());
        appFundDetail2.setType(7);
        appFundDetail2.setAmount(appFundInfo.getFund());
        appFundDetail2.setCreateTime(LocalDateTime.now());
        appFundDetail2.setState(adminFundConfig.getId());
        appFundDetail2.insert();

        /*if( adminFundConfig.getGive() > 0){
            LocalDateTime endTime = LocalDateTime.of(2023, 10, 1, 00, 00, 00);
            if(LocalDateTime.now().isBefore(endTime)){
            for (int i = 0; i < adminFundConfig.getGive(); i++) {
                AppFundInfo fundInfo = new AppFundInfo();
                fundInfo.setUserId(appFundInfo.getUserId());
                fundInfo.setFundId(1);
                fundInfo.setRate(adminFundConfig.getRate());
                fundInfo.setAmount(appFundInfo.getAmount().multiply(adminFundConfig.getRate()));
                fundInfo.setFund(appFundInfo.getFund());
                fundInfo.setExpirationTime(LocalDateTime.now().plusDays(7));
                fundInfo.setCreateTime(LocalDateTime.now());
                fundInfo.setType(1);
                fundInfo.setState(2);
                appFundInfoService.save(fundInfo);

                AppFundDetail appFundDetail1 = new AppFundDetail();
                appFundDetail1.setUserId(appFundInfo.getUserId());
                appFundDetail1.setType(6);
                appFundDetail1.setAmount(appFundInfo.getFund());
                appFundDetail1.setCreateTime(LocalDateTime.now());
                appFundDetail1.setState(1);
                appFundDetail1.insert();

            }}
        }*/

        if (!user.getInviterId().equals(0)) {
            if (appFundInfo.getFundId() >= 3) {
                upgradeUPdate(user.getUserId(), appFundInfo.getFund(), adminFundConfig);
                peerLevelReward(user.getUserId(), appFundInfo.getFund());

                AppUserLamp appUserLamp = appUserLampService.getById(user.getUserId());
                if (ObjectUtils.isEmpty(appUserLamp)) {
                    appUserLamp = new AppUserLamp();
                    appUserLamp.setUserPerformance(appFundInfo.getFund());
                    appUserLamp.setCreateTime(LocalDateTime.now());
                    appUserLamp.setUserId(Integer.valueOf(user.getUserId()));
                    appUserLamp.insert();
                } else {
                    AppUserLamp appUserLamp1 = new AppUserLamp();
                    appUserLamp1.setUserPerformance(appUserLamp.getUserPerformance().add(appFundInfo.getFund()));
                    appUserLamp1.setUserId(user.getUserId());
                    appUserLamp1.updateById();
                }
                AppUserTeamPath appUserTeamPath = appUserTeamPathMapper.selectById(user.getUserId());
                if (appUserTeamPath == null) {
                    return;
                }
                if (appUserTeamPath.getInvitePath() == null || appUserTeamPath.getInvitePath().isEmpty() || appUserTeamPath.getInvitePath().equals("0")) {
                    return;
                }
                String[] path = appUserTeamPath.getInvitePath().split(",");
                appUserLampService.addRealPerformance(path, appFundInfo.getFund());
                appUserLampService.updateLamd(path);

            }
            addTeamValue(user.getUserId(), appFundInfo.getFund());
            updateLevel(user.getInviterId());
            addOrUpdateRanking(user.getInviterId(), appFundInfo.getFund());
        }
        AppUserTeam appUserTeam = appUserTeamMapper.selectById(user.getUserId());
        appUserTeam.setFundCchievement(appUserTeam.getFundCchievement().add(appFundInfo.getFund()));
        appUserTeam.setUpdateTime(LocalDateTime.now());
        appUserTeam.updateById();
    }

    @Override
    @Transactional
    public void v5() {
        List<AppFundLevelInfo> appFundLevelInfos = appFundInfoMapper.getLevelInfoList();
        for (AppFundLevelInfo appFundLevelInfo : appFundLevelInfos) {
            Integer count = appFundInfoMapper.getLevelInfoListByInviterId(appFundLevelInfo.getUserId());
            if (count > 0) {
                for (int i = 0; i < count; i++) {
                    Integer walletId = appUserWalletMapper.checkoutTokenIdAndUserId(LetokenTokenTypeEnum.LET.getId(), appFundLevelInfo.getUserId());
                    if (org.apache.commons.lang3.ObjectUtils.isEmpty(walletId)) {
                        continue;
                    }
                    AppUserWallet w = appUserWalletMapper.selectForUpdate(walletId);
                    AppUserWallet updateW = new AppUserWallet();
                    updateW.setId(w.getId());
                    updateW.setAvailableBalance(w.getAvailableBalance().add(new BigDecimal("15")));
                    appUserWalletMapper.updateById(updateW);

                    AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
                    assetHistory.setUserId(appFundLevelInfo.getUserId());
                    assetHistory.setType(TokenTransactionTypeEnum.V5.getValue());
                    assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
                    assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
                    assetHistory.setAmount(new BigDecimal("15"));
                    assetHistory.setBalance(updateW.getAvailableBalance());
                    assetHistory.setCreateTime(LocalDateTime.now());
                    assetHistory.setUpdateTime(assetHistory.getCreateTime());
                    appUserAssetsHistoryMapper.insert(assetHistory);
                }
            }
        }
    }

    @Override
    @Transactional
    public AppFundV2Info updateInfo(Integer userId, BigDecimal amount,BigDecimal giveAmount) {
        String key = RedisKeyConstant.UPDATE_FUND_INFO + userId;
        RedissonClient redissonClient = redisConfig.getRedisson();
        RLock rlock = redissonClient.getLock(key);
        try {
            rlock.lock(10, TimeUnit.SECONDS);
            log.info("用户获取基金奖励修改数据加锁:"+key);
            AppFundV2Info appFundV2Info = appFundV2InfoMapper.selectForUpdate(userId);
            AppFundV2Info appFundV2Info1 = new AppFundV2Info();
            appFundV2Info1.setRetained(appFundV2Info.getRetained().subtract(amount));
            appFundV2Info1.setGive(appFundV2Info.getGive().subtract(giveAmount));
            appFundV2Info1.setUserId(userId);
            appFundV2Info1.setUpdateTime(LocalDateTime.now());
            appFundV2InfoMapper.updateById(appFundV2Info1);
            log.info("用户基金奖励:"+appFundV2Info.getUserId()+"奖励前金额:"+appFundV2Info.getRetained()+"奖励后金额:"+appFundV2Info1.getRetained());
            return appFundV2Info1;
        }finally {
                if (rlock != null && rlock.isHeldByCurrentThread()) {
                    rlock.unlock();
                }
            }
    }

    @Override
    public void transferInCAP(FundTransferReq req) {
        AppUserWallet w = appUserWalletMapper.selectForUpdate(req.getWalletId());
        if (w.getAvailableBalance().compareTo(req.getAmount()) < 0){
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_053);
        }
        if (req.getAmount().compareTo(req.getAdminFundConfig().getMin())<0){
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_053,req.getAdminFundConfig().getMin());
        }
        AppUserWallet updateW = new AppUserWallet();
        updateW.setId(w.getId());
        updateW.setAvailableBalance(w.getAvailableBalance().subtract(req.getAmount()));
        appUserWalletMapper.updateById(updateW);


        AppFundInfo appFundInfo = new AppFundInfo();
        appFundInfo.setUserId(req.getUserId());
        appFundInfo.setFundId(req.getAdminFundConfig().getId());
        appFundInfo.setRate(req.getAdminFundConfig().getRate());
        appFundInfo.setAmount(req.getAmount().multiply(req.getAdminFundConfig().getRate()));
        appFundInfo.setFund(req.getAmount());
        appFundInfo.setExpirationTime(LocalDateTime.now().plusDays(req.getAdminFundConfig().getDate()));
        appFundInfo.setCreateTime(LocalDateTime.now());
        appFundInfo.setType(1);
        appFundInfo.setUrl(req.getAdminFundConfig().getUrl());
        appFundInfo.setState(1);
        appFundInfoService.save(appFundInfo);

        AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
        assetHistory.setUserId(req.getUserId());
        assetHistory.setType(TokenTransactionTypeEnum.CAP_FUND_Staking.getValue());
        assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
        assetHistory.setTokenId(LetokenTokenTypeEnum.CAP.getId());
        assetHistory.setAmount(req.getAmount().negate());
        assetHistory.setSn(appFundInfo.getId().toString());
        assetHistory.setBalance(updateW.getAvailableBalance());
        assetHistory.setCreateTime(LocalDateTime.now());
        assetHistory.setUpdateTime(assetHistory.getCreateTime());
        appUserAssetsHistoryMapper.insert(assetHistory);
        AppUser user = appUserManager.queryMe();

        AppFundDetail appFundDetail = new AppFundDetail();
        appFundDetail.setUserId(req.getUserId());
        appFundDetail.setType(4);
        appFundDetail.setAmount(req.getAmount());
        appFundDetail.setState(req.getAdminFundConfig().getId());
        appFundDetail.setCreateTime(LocalDateTime.now());
        appFundDetail.setTitle(req.getAdminFundConfig().getTitle()+"-质押");
        appFundDetail.setRemark("+");
        appFundDetail.insert();


        if (!user.getInviterId().equals(0)){
            if(req.getAdminFundConfig().getGive().equals(1)){
                Integer upId = appFundInfoMapper.getLevel(user.getId());
                if(upId !=null && !upId.equals(0)){
                    if(appFundInfoMapper.sumFundByUserIdAndType(upId).compareTo(new BigDecimal("10000"))>=0){
                        BigDecimal ss = req.getAmount().multiply(new BigDecimal("0.1"));
                        appUserWalletService.updateWallet(LetokenTokenTypeEnum.CAP.getId(),upId,ss, TokenTransactionTypeEnum.CAP_FUND_Dividends.getValue(),"");

                        AppFundDetail appFundDetail2 = new AppFundDetail();
                        appFundDetail2.setUserId(upId);
                        appFundDetail2.setType(2);
                        appFundDetail2.setAmount(ss);
                        appFundDetail2.setState(req.getAdminFundConfig().getId());
                        appFundDetail2.setCreateTime(LocalDateTime.now());
                        appFundDetail2.setTitle(TokenTransactionTypeEnum.CAP_FUND_Dividends.getText());
                        appFundDetail2.insert();
                    }
                }
            }
        }
    }
    @Transactional
    @Override
    public void fundCapJob() {
        List<Integer> fundUserIdList= appFundInfoMapper.getFundUserId();
        List<AdminFundConfig> configList = adminFundConfigMapper.selectList(new QueryWrapper<>());

        for (Integer userId:fundUserIdList) {
            List<AppFundInfo> infoList = appFundInfoMapper.getFundByUserId(userId);
            //自己可拿奖励总额
            BigDecimal sumFund = BigDecimal.ZERO;

            for (AppFundInfo appFundInfo : infoList) {
                BigDecimal rate = configList.stream().filter(s -> s.getId().equals(appFundInfo.getFundId())).collect(Collectors.toList()).get(0).getRate();
                appFundInfo.setAmount(appFundInfo.getFund().multiply(rate));
                sumFund = sumFund.add(appFundInfo.getAmount());
            }
            AppFundDetail appFundDetail = new AppFundDetail();
            appFundDetail.setAmount(sumFund);
            appFundDetail.setCreateTime(LocalDateTime.now());
            appFundDetail.setType(1);
            appFundDetail.setUserId(userId);
            appFundDetail.setTitle(TokenTransactionTypeEnum.CAP_FUND_Circulation.getText());
            appFundDetail.insert();
            appUserWalletService.updateWallet(LetokenTokenTypeEnum.CAP.getId(),userId,sumFund, TokenTransactionTypeEnum.CAP_FUND_Circulation.getValue(),"");

        }
    }

    public void addTeamValue(Integer userId, BigDecimal amount) {
        AppUserTeamPath appUserTeamPath = appUserTeamPathMapper.selectById(userId);
        if (appUserTeamPath == null) {
            return;
        }
        if (appUserTeamPath.getInvitePath() == null || appUserTeamPath.getInvitePath() == "" || appUserTeamPath.getInvitePath() == "0") {
            return;
        }
        String[] path = appUserTeamPath.getInvitePath().split(",");
        List<AppUserTeam> teamList = new ArrayList<>();
        for (String inviteID : path) {
            AppUserTeam appUserTea1 = new AppUserTeam();
            AppUserTeam appUserTeam = appUserTeamMapper.selectById(inviteID);
            if (appUserTeam == null) {
                break;
            }
            appUserTea1.setUserId(appUserTeam.getUserId());
            appUserTea1.setTeamfundAchievement(appUserTeam.getTeamfundAchievement().add(amount));
            teamList.add(appUserTea1);
        }
        appUserTeamService.updateBatchById(teamList);


    }


    public void upgradeUPdate(Integer userId, BigDecimal amount, AdminFundConfig adminFundConfig) {
        if (adminFundConfig.getEcoRate().compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        BigDecimal money = BigDecimal.ZERO;
        AppUserTeamPath teamPath = appUserTeamPathMapper.selectById(userId);
        String[] path = teamPath.getInvitePath().split(",");
        List<AppUserTeam> teamList = new ArrayList<>();
        Integer id = userId;
        for (String inviteID : path) {
            Integer invite = Integer.parseInt(inviteID);
            AppUserTeam appUserTeam = appUserTeamMapper.selectById(inviteID);
            AppUserTeam appUserTeam1 = new AppUserTeam();
            appUserTeam1.setUserId(invite);
            if (appUserTeam == null) {
                continue;
            }
            List<AppUserTeam> team = appUserTeamMapper.getMAXFundTeamValueSize(invite);
            if (team == null || team.size() == 0) {
                id = invite;
                continue;
            } else {
                Integer finalId = id;
                List<AppUserTeam> appUserTeams = team.stream().filter(t -> t.getUserId().equals(finalId)).collect(Collectors.toList());
                if (appUserTeams.isEmpty()) {
                    AppUserTeam userTeam = team.get(0);
                    AppUserTeam appUserTeam2 = appUserTeamMapper.getAchievement(finalId);
                    BigDecimal bigDecimal = new BigDecimal(userTeam.getTeamValue()).subtract(appUserTeam2.getFundCchievement().add(appUserTeam2.getTeamfundAchievement()));
                    money = bigDecimal.compareTo(amount) > 0 ? amount : bigDecimal;
                } else {
                    id = invite;
                    continue;
                }
            }
            appUserTeam1.setEcoValue(appUserTeam.getEcoValue().add((money.multiply(adminFundConfig.getEcoRate()))));
            teamList.add(appUserTeam1);
            id = invite;
        }
        if (teamList.size() > 0) {
            appUserTeamService.updateBatchById(teamList);
        }

    }

    private void updateLevel(Integer inviterId) {
        AppFundLevelInfo info = appFundLevelInfoMapper.selectById(inviterId);
        List<AdminFundLevelConfig> levelConfigs = adminFundLevelConfigMapper.getLevelList();
        if (info == null || info.getLevel() < levelConfigs.size()) {
            Integer count = appFundLevelInfoMapper.getFundByInviterIdCOunt(inviterId);
            Integer count2 = appFundLevelInfoMapper.getFundByUserIdAndType(inviterId);
            if (count2 > 0) {
                for (AdminFundLevelConfig adminFundLevelConfig : levelConfigs) {
                    if (count >= adminFundLevelConfig.getCondition()) {
                        AppFundLevelInfo appFundLevelInfo = new AppFundLevelInfo();
                        appFundLevelInfo.setLevel(adminFundLevelConfig.getLevel());
                        appFundLevelInfo.setUserId(inviterId);
                        appFundLevelInfo.setUpdateTime(LocalDateTime.now());
                        appFundLevelInfo.insertOrUpdate();
                        break;
                    }
                }
            }/*else {
              AppFundLevelInfo appFundLevelInfo = new AppFundLevelInfo();
              appFundLevelInfo.setLevel(0);
              appFundLevelInfo.setUserId(inviterId);
              appFundLevelInfo.insertOrUpdate();
          }*/
        }
    }


    private void addOrUpdateRanking(Integer userId, BigDecimal amount) {
        LocalDateTime now = LocalDateTime.now();
        String threshold = now.getYear()+"-"+now.getMonthValue()+"-"+now.getDayOfMonth()+" 18:00:00";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d HH:mm:ss");
        LocalDateTime dateTime = LocalDateTime.parse(threshold, formatter);
        String startTime;
        String endTime;
        if(now.isAfter(dateTime) == true){
            startTime = threshold;
            now = now.plusDays(1);
            endTime = now.getYear()+"-"+now.getMonthValue()+"-"+now.getDayOfMonth()+" 18:00:00";
        }else{
            endTime = threshold;
            dateTime = dateTime.plusDays(-1);
            startTime = dateTime.getYear()+"-"+dateTime.getMonthValue()+"-"+dateTime.getDayOfMonth()+" 18:00:00";;
        }
        // 记录每天的直推业绩
        AppFundRanking appFundRanking = appFundRankingMapper.getAppFundRanking(userId,startTime,endTime);
        if (Objects.isNull(appFundRanking)) {
            appFundRanking = new AppFundRanking();
            appFundRanking.setAmount(amount);
            appFundRanking.setType(1);
            appFundRanking.setUserId(userId);
            appFundRanking.setCreateTime(LocalDateTime.now());
            appFundRanking.setUpdateTime(LocalDateTime.now());
            appFundRanking.insert();
        } else {
            appFundRanking.setUpdateTime(LocalDateTime.now());
            appFundRanking.setAmount(appFundRanking.getAmount().add(amount));
            appFundRanking.updateById();
        }
    }

    private void peerLevelReward(Integer userId, BigDecimal amount) {
        BigDecimal rate = appFundInfoMapper.getMaxLevelRate();
        List<UserLevelReq> user = appFundInfoMapper.selectUserLevelPeerRate(userId);
        //上一次拿奖励的人等级
        Integer level = 0;
        BigDecimal levelRate = BigDecimal.ZERO;
        if (user.size() > 0) {
            for (UserLevelReq req : user) {
                if (req.getLevel() > level && rate.compareTo(BigDecimal.ZERO) > 0) {

                    if (!calculateConsumerValue.hasKey(calculateConsumerValue.getKey(), String.valueOf(req.getUserId())) && !calculateConsumerValue.isNewUser(req.getUserId())) {
                        log.info("服务奖：用户{}不满足消费值条件", req.getUserId());
                        continue;
                    }

                    BigDecimal rates = req.getRate();
                    req.setRate(req.getRate().subtract(levelRate));
                    BigDecimal ss = rate.compareTo(req.getRate()) > 0 ? req.getRate() : rate;
                    BigDecimal reward = amount.multiply(ss);
                    rate = rate.compareTo(req.getRate()) > 0 ? rate.subtract(req.getRate()) : BigDecimal.ZERO;
                    level = req.getLevel();
                    levelRate = rates;
                    // BigDecimal bigDecimal = appFundInfoMapper.sumAmount(req.getUserId(),3);;
                    /*BigDecimal bigDecimal = appFundInfoMapper.sumAmount(req.getUserId(), 3);
                    if (bigDecimal.compareTo(BigDecimal.ZERO) <= 0) {
                        continue;
                    }*/
                    if (reward.compareTo(BigDecimal.ZERO)<=0) continue;
                    AppFundV2Info appFundV2Info = appFundV2InfoMapper.selectBYUserId(req.getUserId());
                    if(ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(BigDecimal.ZERO) == 0)continue;

                    if(ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(req.getAmount()) < 0 || rates.compareTo(BigDecimal.ZERO)<=0){
                        log.info("服务奖：用户{}不满足服务奖留存金额", req.getUserId());
                        continue;
                    }

                    if(reward.compareTo(appFundV2Info.getRetained()) > 0){
                        reward = appFundV2Info.getRetained();
                    }

                    AppFundV2Info appFundV2Info1 = appFundInfoService.updateInfo(appFundV2Info.getUserId(),reward,BigDecimal.ZERO);

                    /*AppFundV2Info appFundV2Info1 = new AppFundV2Info();
                    appFundV2Info1.setUserId(appFundV2Info.getUserId());
                    appFundV2Info1.setRetained(appFundV2Info.getRetained().subtract(reward));
                    appFundV2Info1.updateById();*/

                    AppFundV2Detail appFundV2Detail = new AppFundV2Detail();
                    appFundV2Detail.setAmount(reward);
                    appFundV2Detail.setUserId(req.getUserId());
                    appFundV2Detail.setCreateTime(LocalDateTime.now());
                    appFundV2Detail.setAfterAmount(appFundV2Info1.getRetained());
                    appFundV2Detail.setType(6);
                    appFundV2Detail.setSourceUserId(userId);
                    appFundV2Detail.insert();

                    appUserWalletService.updateWallet(LetokenTokenTypeEnum.LET.getId(),appFundV2Info.getUserId(),reward,TokenTransactionTypeEnum.FUND_LEVEL_REWARD.getValue(),"");


                    /*Integer walletId = appUserWalletMapper.checkoutTokenIdAndUserId(LetokenTokenTypeEnum.LET.getId(), req.getUserId());
                    AppUserWallet w = appUserWalletMapper.selectForUpdate(walletId);
                    AppUserWallet updateW = new AppUserWallet();
                    updateW.setId(w.getId());
                    updateW.setAvailableBalance(w.getAvailableBalance().add(reward));
                    appUserWalletMapper.updateById(updateW);

                    AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
                    assetHistory.setUserId(req.getUserId());
                    assetHistory.setType(TokenTransactionTypeEnum.FUND_LEVEL_REWARD.getValue());
                    assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
                    assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
                    assetHistory.setAmount(reward);
                    assetHistory.setBalance(updateW.getAvailableBalance());
                    assetHistory.setCreateTime(LocalDateTime.now());
                    assetHistory.setUpdateTime(assetHistory.getCreateTime());
                    appUserAssetsHistoryMapper.insert(assetHistory);*/
                    appUserLampService.updateLamd(req.getUserId(),reward.negate());

                }
            }
        }

    }


    private void communityReward(Integer userId, BigDecimal amount) {
        BigDecimal rate = adminCommunityConfigMapper.maxRate();
        List<UserLevelReq> user = adminCommunityConfigMapper.selectUserLevelCommunity(userId);
        //上一次拿奖励的人等级
        Integer level = 0;
        BigDecimal levelRate = BigDecimal.ZERO;
        if (user.size() > 0) {
            for (UserLevelReq req : user) {
                if (req.getLevel() > level && rate.compareTo(BigDecimal.ZERO) > 0) {

                    BigDecimal rates = req.getRate();
                    req.setRate(req.getRate().subtract(levelRate));
                    BigDecimal ss = rate.compareTo(req.getRate()) > 0 ? req.getRate() : rate;
                    BigDecimal reward = amount.multiply(ss);
                    rate = rate.compareTo(req.getRate()) > 0 ? rate.subtract(req.getRate()) : BigDecimal.ZERO;
                    level = req.getLevel();
                    levelRate = rates;
                    // BigDecimal bigDecimal = appFundInfoMapper.sumAmount(req.getUserId(),3);;
                    /*BigDecimal bigDecimal = appFundInfoMapper.sumAmount(req.getUserId(), 3);
                    if (bigDecimal.compareTo(BigDecimal.ZERO) <= 0) {
                        continue;
                    }*/
                    if (reward.compareTo(BigDecimal.ZERO)<=0) continue;
                    AppFundV2Info appFundV2Info = appFundV2InfoMapper.selectBYUserId(req.getUserId());
                    if(ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(BigDecimal.ZERO) == 0)continue;
                    if(ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(req.getAmount()) < 0 || rates.compareTo(BigDecimal.ZERO)<=0){
                        log.info("服务奖：用户{}不满足服务奖留存金额", req.getUserId());
                        continue;
                    }

                  /*  if(reward.compareTo(appFundV2Info.getRetained()) > 0){
                        reward = appFundV2Info.getRetained();
                    }*/

                    appUserWalletService.updateWallet(LetokenTokenTypeEnum.LET.getId(),appFundV2Info.getUserId(),reward,TokenTransactionTypeEnum.community.getValue(),"");


                    /*Integer walletId = appUserWalletMapper.checkoutTokenIdAndUserId(LetokenTokenTypeEnum.LET.getId(), req.getUserId());
                    AppUserWallet w = appUserWalletMapper.selectForUpdate(walletId);
                    AppUserWallet updateW = new AppUserWallet();
                    updateW.setId(w.getId());
                    updateW.setAvailableBalance(w.getAvailableBalance().add(reward));
                    appUserWalletMapper.updateById(updateW);

                    AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
                    assetHistory.setUserId(req.getUserId());
                    assetHistory.setType(TokenTransactionTypeEnum.community.getValue());
                    assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
                    assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
                    assetHistory.setAmount(reward);
                    assetHistory.setBalance(updateW.getAvailableBalance());
                    assetHistory.setCreateTime(LocalDateTime.now());
                    assetHistory.setUpdateTime(assetHistory.getCreateTime());
                    appUserAssetsHistoryMapper.insert(assetHistory);*/
                   // appUserLampService.updateLamd(req.getUserId(),reward.divide(new BigDecimal(5)).negate());

                }
            }
        }

    }


    private void communityV2Reward(Integer userId, BigDecimal amount) {
        BigDecimal rate = adminCommunityConfigMapper.maxRewardRate();
        List<UserLevelReq> user = adminCommunityConfigMapper.selectUserLevelCommunity(userId);
        //上一次拿奖励的人等级
        Integer level = 0;
        BigDecimal levelRate = BigDecimal.ZERO;
        if (user.size() > 0) {
            for (UserLevelReq req : user) {
                if (req.getLevel() > level && rate.compareTo(BigDecimal.ZERO) > 0) {

                    BigDecimal rates = req.getRewardRate();
                    req.setRate(req.getRewardRate().subtract(levelRate));
                    BigDecimal ss = rate.compareTo(req.getRewardRate()) > 0 ? req.getRewardRate() : rate;
                    BigDecimal reward = amount.multiply(ss);
                    rate = rate.compareTo(req.getRewardRate()) > 0 ? rate.subtract(req.getRewardRate()) : BigDecimal.ZERO;
                    level = req.getLevel();
                    levelRate = rates;

                    if (reward.compareTo(BigDecimal.ZERO)<=0) continue;
                    AppFundV2Info appFundV2Info = appFundV2InfoMapper.selectBYUserId(req.getUserId());
                   // if(ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(BigDecimal.ZERO) == 0)continue;
                    if(ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(req.getRetainedV2()) < 0 || rates.compareTo(BigDecimal.ZERO)<=0){
                        log.info("服务奖：用户{}不满足服务奖留存金额", req.getUserId());
                        continue;
                    }

                    if(reward.compareTo(appFundV2Info.getRetained()) > 0){
                        reward = appFundV2Info.getRetained();
                    }


                    AppFundV2Info appFundV2Info1 = appFundInfoService.updateInfo(appFundV2Info.getUserId(),reward,BigDecimal.ZERO);

                    AppFundV2Detail appFundV2Detail = new AppFundV2Detail();
                    appFundV2Detail.setAmount(reward);
                    appFundV2Detail.setUserId(appFundV2Info.getUserId());
                    appFundV2Detail.setCreateTime(LocalDateTime.now());
                    appFundV2Detail.setAfterAmount(appFundV2Info1.getRetained());
                    appFundV2Detail.setType(8);
                    appFundV2Detail.insert();

                    appUserWalletService.updateWallet(LetokenTokenTypeEnum.LET.getId(),appFundV2Info.getUserId(),reward,TokenTransactionTypeEnum.communityV2.getValue(),"");

                    appUserLampService.updateLamd(req.getUserId(),reward.negate());

                }
            }
        }

    }


}
